package com.rock.platform.util;

import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import net.sf.ezmorph.object.DateMorpher;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import net.sf.json.util.CycleDetectionStrategy;
import net.sf.json.util.JSONUtils;

public class JsonUtils {
	public static void registerMorpher() {
		registerMorpher(new String[] { "yyyy-MM-dd HH:mm:ss", "yyyy-MM-dd" });
	}

	public static void registerMorpher(String[] dateFormats) {
		JSONUtils.getMorpherRegistry().registerMorpher(
				new DateMorpher(dateFormats));
	}

	public static JsonConfig configJson(String datePattern) {
		String[] excludes = { "" };
		return configJson(excludes, datePattern);
	}

	public static JsonConfig configJson(String[] excludes, String datePattern) {
		JsonConfig jsonConfig = new JsonConfig();
		jsonConfig.setExcludes(excludes);
		jsonConfig.setIgnoreDefaultExcludes(false);
		jsonConfig.setCycleDetectionStrategy(CycleDetectionStrategy.LENIENT);
		jsonConfig.registerJsonValueProcessor(Date.class,
				new DateJsonValueProcessor(datePattern));
		return jsonConfig;
	}

	public static <T> T getEntity(String jsonString, Class<T> c) {
		return getEntity(jsonString, c, null);
	}

	public static <T> T getEntity(String jsonString, Class<T> c,
			Map<String, Class<?>> classMap) {
		registerMorpher();

		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		return toBean(jsonObject, c, classMap);
	}

	public static <T> List<T> getEntityList(String jsonString, Class<T> c) {
		return getEntityList(jsonString, c, null);
	}

	public static <T> List<T> getEntityList(String jsonString, Class<T> c,
			Map<String, Class<?>> classMap) {
		registerMorpher();

		JSONArray jsonArray = JSONArray.fromObject(jsonString);
		return toBean(jsonArray, c, classMap);
	}

	public static Map<String, Object> getMap(String jsonString) {
		registerMorpher();

		JSONObject jsonObject = JSONObject.fromObject(jsonString);
		Iterator<?> keyIter = jsonObject.keys();

		Map<String, Object> valueMap = new HashMap<String, Object>();
		while (keyIter.hasNext()) {
			String key = (String) keyIter.next();
			Object value = jsonObject.get(key);
			valueMap.put(key, value);
		}

		return valueMap;
	}

	public static Object[] getObjectArray(String jsonString) {
		registerMorpher();

		JSONArray jsonArray = JSONArray.fromObject(jsonString);
		return jsonArray.toArray();
	}

	public static <T> T toBean(JSONObject jsonObject, Class<T> c) {
		return toBean(jsonObject, c, null);
	}

	@SuppressWarnings("unchecked")
	public static <T> T toBean(JSONObject jsonObject, Class<T> c,
			Map<String, Class<?>> classMap) {
		if (classMap == null) {
			return (T) JSONObject.toBean(jsonObject, c);
		}

		return (T) JSONObject.toBean(jsonObject, c, classMap);
	}

	public static <T> List<T> toBean(JSONArray jsonArray, Class<T> c) {
		return toBean(jsonArray, c, null);
	}

	@SuppressWarnings("unchecked")
	public static <T> List<T> toBean(JSONArray jsonArray, Class<T> c,
			Map<String, Class<?>> classMap) {
		JSONObject jsonObject = null;
		Object entity = null;

		List<T> list = new ArrayList<T>();
		for (int i = 0; i < jsonArray.size(); ++i) {
			jsonObject = jsonArray.getJSONObject(i);
			entity = toBean(jsonObject, c, classMap);
			list.add((T) entity);
		}

		return list;
	}

	public static <T> String getJsonString(T entity) {
		return getJsonString(entity, "yyyy-MM-dd HH:mm:ss");
	}

	public static <T> String getJsonString(T entity, String dateFormat) {
		JsonConfig jsonConfig = configJson(dateFormat);
		if (entity instanceof List) {
			return JSONArray.fromObject(entity, jsonConfig).toString();
		}
		return JSONObject.fromObject(entity, jsonConfig).toString();
	}

	public static <T> String getJsonString(List<T> lst) {
		return getJsonString(lst, "yyyy-MM-dd HH:mm:ss");
	}

	public static <T> String getJsonString(List<T> lst, String dateFormat) {
		JsonConfig jsonConfig = configJson(dateFormat);

		return JSONArray.fromObject(lst, jsonConfig).toString();
	}
}
